package com.wb.designmode.mqtt;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.assertj.core.util.Maps;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ServerMQTT {

    private final Logger logger = LoggerFactory.getLogger(ServerMQTT.class);

    // tcp://MQTT安装的服务器地址:MQTT定义的端口号
    public static final String HOST = "tcp://wb-sys.tpddns.cn:1883";
    // 定义一个主题
    public static final String TOPIC = "/demo/test1";
    // 定义MQTT的ID，可以在MQTT服务配置中指定
    private static final String clientid = "server11";

    private MqttClient client;
    private MqttTopic topic11;
    private String userName = "wangbo_mqtt1";
    private String passWord = "wb";

    Random random = new Random(100);

    ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    private Object lock = new Object();

    private MqttMessage message;

    /**
     * 构造函数
     *
     * @throws MqttException
     */
    public ServerMQTT() throws MqttException {
        // MemoryPersistence设置clientid的保存形式，默认为以内存保存
        client = new MqttClient(HOST, clientid, new MemoryPersistence());
        connect();
    }

    /**
     * 用来连接服务器
     */
    private void connect() {
        MqttConnectOptions options = new MqttConnectOptions();
        options.setCleanSession(false);
        options.setUserName(userName);
        options.setPassword(passWord.toCharArray());
        // 设置超时时间
        options.setConnectionTimeout(10);
        // 设置会话心跳时间
        options.setKeepAliveInterval(20);
        try {
            client.setCallback(new PushCallback());
            client.connect(options);

            topic11 = client.getTopic(TOPIC);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     *
     * @param topic
     * @param message
     * @throws MqttPersistenceException
     * @throws MqttException
     */
    public void publish(MqttTopic topic, MqttMessage message) throws MqttPersistenceException, MqttException {
        MqttDeliveryToken token = topic.publish(message);
        token.waitForCompletion();
        System.out.println("message is published completely! " + token.isComplete());
    }

    /**
     * 启动入口
     *
     * @param args
     * @throws MqttException
     */
//    public static void main(String[] args) throws MqttException {

    @Test
    public void serverMqtt() {
        scheduler.scheduleAtFixedRate(new WhilePub(),0,2, TimeUnit.SECONDS);
        synchronized (lock) {
            try {
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    class WhilePub implements Runnable {

        int count = 0;

        @Override
        public void run() {
            this.contecton();
        }

        public void contecton() {
            try {
                ServerMQTT server = new ServerMQTT();

                Map<String,String> paramsMap = Maps.newHashMap("serialNumber","SN-001");
                paramsMap.put("sensorType","Thermometer");
                paramsMap.put("sensorModel" , "T1000");
                paramsMap.put("temp", String.valueOf(random.nextInt(100)));
                paramsMap.put("hum", String.valueOf(random.nextInt(100)));

                ObjectMapper objectMapper = new ObjectMapper();
                try {
                    String value = objectMapper.writeValueAsString(paramsMap);

                    logger.info("value : {}" , value);

                    server.message = new MqttMessage();
                    server.message.setQos(1);
                    server.message.setRetained(true);
                    server.message.setPayload(value.getBytes());
                    server.publish(server.topic11, server.message);
                    System.out.println(server.message.isRetained() + "------ratained状态");
                } catch (JsonProcessingException e) {
                    logger.error("" , e);
                    this.contecton();
                }
            } catch (MqttException e) {
                logger.error("", e);
                this.contecton();
            } catch (Exception e) {
                logger.error("", e);
                this.contecton();
            } finally {
                if (count > 3) {
                    return;
                }
            }
        }
    }
}
